#include "dulinklist.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"


/**
 * 功 能：
 *      创建一个链表
 * 参 数：
 *      无
 * 返回值：
 *      成功：操作句柄
 *      失败：NULL
 **/
dulinklist_t *dulinklist_create()
{
    dulinklist_t *list = (dulinklist_t *)malloc(sizeof(dulinklist_t));
    if (list == null) return NULL;
    
    list->next = NULL;
    list->prev = NULL;
    list->data = 0;

    return list;
}

/**
 * 功 能：
 *      链表头部插法节点
 * 参 数：
 *      list: 要操作的链表
 *      data: 插入的数据
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int dulinklist_insert_head(dulinklist_t *list, int data)
{
    if(list == NULL) return -1;
    
    dulinklist_t *node = (dulinklist_t *)malloc(sizeof(dulinklist_t));

    node->data = data;

    node->next = list->next;
    node->prev = list;

    /* 如果是第一次插入节点，则需要进行处理，因为 list->next = NULL */
    if (node->next != NULL)
        node->next->prev = node;
    list->next = node;

    return 0;
}

/**
 * 功 能：
 *      链表尾部插法节点
 * 参 数：
 *      list: 要操作的链表
 *      data: 插入的数据
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int dulinklist_insert_tail(dulinklist_t *list, int data)
{
    if (list == NULL) return -1;
    dulinklist_t *current = list;
    dulinklist_t *node = (dulinklist_t *)malloc(sizeof(dulinklist_t));
    
    node->data = data;
    /* 将指针向后移动 */
    while (NULL != current->next)
        current = current->next;
    
    current->next = node;
    node->prev = current;
    node->next = NULL;

    return 0;
}

/**
 * 功 能：
 *      链表的指定位置pos插入节点
 * 参 数：
 *      list: 要操作的链表
 *      data: 插入的数据
 *      pos : 要插入节点的位置
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int dulinklist_insert(dulinklist_t *list, int data, int pos)
{
    dulinklist_t *current = list;

    if(list == NULL || pos < 0) return -1;

    dulinklist_t *node = (dulinklist_t *)malloc(sizeof(dulinklist_t));

    while (current->next != NULL && pos--) 
        current = current->next;

    node->next = current->next;
    current->next = node;
    node->prev = current;

    /* 第一次插入节点，需要额外的处理 */
    if(node->next != NULL) 
        node->next->prev = node;

    node->data = data;

    return 0;
}

/**
 * 功 能：
 *      删除链表的指定位置pos节点
 * 参 数：
 *      list: 要操作的链表
 *      pos : 要删除节点的位置
 * 返回值：
 *      成功：删除的节点
 *      失败：NULL
 **/
dulinklist_t* dulinklist_delete_pos(dulinklist_t *list, int pos)
{
    if(list == NULL || pos < 0) return NULL;

    dulinklist_t *ret = NULL;
    dulinklist_t *current = list;
    dulinklist_t *next = NULL;

    while(current->next->next != NULL && pos --)
        current = current->next;

    ret = current->next;
    next = ret->next;
    current->next = ret->next;
    
    if(next != NULL)
        next->prev = current;

    return ret;
}


/**
 * 功 能：
 *      获取链表的长度
 * 参 数：
 *      list: 要操作的链表
 * 返回值：
 *      成功：链表的长度
 *      失败：-1
 **/
int dulinklist_length(dulinklist_t *list)
{
    int len = 0;

    if(list == NULL) return -1;
    while (list->next)
    {
        list = list->next;
        len ++;
    }
    return len;
}

/**
 * 功 能：
 *      从头节点开始往后遍历链表
 * 参 数：
 *      list: 要操作的链表
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int dulinklist_display_next(dulinklist_t *list)
{
    if(list == NULL) return -1;
    while (list->next != NULL)
    {
        list = list->next;
        printf("%-3d ", list->data);
    }
    putchar(10);
    return 0;
}

/**
 * 功 能：
 *      从最后一个节点开始往前遍历链表
 * 参 数：
 *      list: 要操作的链表
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int dulinklist_display_prev(dulinklist_t *list)
{
    if(list == NULL) return -1;
    while (list->next != NULL)
    {
        list = list->next;
    }
    while (list->prev != NULL)
    {
        printf("%-3d ", list->data);
        list = list->prev;
    }
    putchar(10);
    return 0;
}




